﻿(function() {
    nova.widgets.ShakeManager = function () {
        this.watchFrequency = 20;
        this.stopOnShaked = true;
        this.lastAcceleration = null;
        this.watchId = null;
        this.minShakeDistance = 17;
        this.minShakeGravity = 10;
        this.minShakedCount = 3;
        this._shakedCounter = 0;
    };

    nova.widgets.ShakeManager.prototype = {
        start: function() {
            var obj = this;
            obj.lastAcceleration = null;
            obj._shakedCounter = 0;
            obj.watchId = navigator.accelerometer.watchAcceleration(function(acceleration) {
                if (obj.lastAcceleration == null) {
                    obj.lastAcceleration = acceleration;
                    return;
                }
                if (obj.lastAcceleration.timestamp == acceleration.timestamp) {
                    return;
                }
                var dx = Math.abs(acceleration.x - obj.lastAcceleration.x);
                var dy = Math.abs(acceleration.y - obj.lastAcceleration.y);
                var dz = Math.abs(acceleration.z - obj.lastAcceleration.z);
                var shaked = dx > obj.minShakeDistance || dy > obj.minShakeDistance || dz > obj.minShakeGravity;
                if (shaked) {
                    obj._shakedCounter++;
                    if (obj._shakedCounter >= obj.minShakedCount) {
                        navigator.notification.vibrate(500);
                        obj._shakedCounter = 0;
                        if (obj.stopOnShaked) {
                            obj.stop();
                        }
                        $(obj).trigger('onShaked');
                    }
                }
                obj.lastAcceleration = acceleration;
            },
                function() {
                    $(obj).trigger('onError');
                },
                {
                    frequency: obj.watchFrequency
                });
        },
        stop: function() {
            navigator.accelerometer.clearWatch(this.watchId);
        },
        onShaked: function(handler) {
            $(this).bind('onShaked', handler);
        },
        onError: function(handler) {
            $(this).bind('onError', handler);
        }
    };
})();

